/*
 * ! Ext JS Library 3.0.0 Copyright(c) 2006-2009 Ext JS, LLC licensing@extjs.com
 * http://www.extjs.com/license
 */
/**
 * @class Ext.ux.StatusBar
 *        <p>
 *        Basic status bar component that can be used as the bottom toolbar of
 *        any {@link Ext.Panel}. In addition to supporting the standard
 *        {@link Ext.Toolbar} interface for adding buttons, menus and other
 *        items, the StatusBar provides a greedy status element that can be
 *        aligned to either side and has convenient methods for setting the
 *        status text and icon. You can also indicate that something is
 *        processing using the {@link #showBusy} method.
 *        </p>
 *        <p>
 *        <b>Note:</b> Although StatusBar supports xtype:'statusbar', at this
 *        time Ext.Toolbar (the base class) does not support xtype. For this
 *        reason, if you are adding Toolbar items into the StatusBar you must
 *        declare it using the "new StatusBar()" syntax for the items to render
 *        correctly.
 *        </p>
 * 
 * <pre><code>
 * new Ext.Panel({
 * 			title : 'StatusBar',
 * 			// etc.
 * 			bbar : new Ext.ux.StatusBar({
 * 						id : 'my-status',
 * 
 * 						// defaults to use when the status is cleared:
 * 						defaultText : 'Default status text',
 * 						defaultIconCls : 'default-icon',
 * 
 * 						// values to set initially:
 * 						text : 'Ready',
 * 						iconCls : 'ready-icon',
 * 
 * 						// any standard Toolbar items:
 * 						items : [{
 * 									text : 'A Button'
 * 								}, '-', 'Plain Text']
 * 					})
 * 		});
 * 
 * // Update the status bar later in code:
 * var sb = Ext.getCmp('my-status');
 * sb.setStatus({
 * 	text : 'OK',
 * 	iconCls : 'ok-icon',
 * 	clear : true
 * 		// auto-clear after a set interval
 * 	});
 * 
 * // Set the status bar to show that something is processing:
 * sb.showBusy();
 * 
 * // processing....
 * 
 * sb.clearStatus(); // once completeed
 * </code></pre>
 * 
 * @extends Ext.Toolbar
 * @constructor Creates a new StatusBar
 * @param {Object/Array}
 *            config A config object
 */
Ext.ux.StatusBar = Ext.extend(Ext.Toolbar, {
	/**
	 * @cfg {String} statusAlign The alignment of the status element within the
	 *      overall StatusBar layout. When the StatusBar is rendered, it creates
	 *      an internal div containing the status text and icon. Any additional
	 *      Toolbar items added in the StatusBar's {@link #items} config, or
	 *      added via {@link #add} or any of the supported add* methods, will be
	 *      rendered, in added order, to the opposite side. The status element
	 *      is greedy, so it will automatically expand to take up all sapce left
	 *      over by any other items. Example usage:
	 * 
	 * <pre><code>
	 * // Create a left-aligned status bar containing a button,
	 * // separator and text item that will be right-aligned (default):
	 * new Ext.Panel({
	 * 			title : 'StatusBar',
	 * 			// etc.
	 * 			bbar : new Ext.ux.StatusBar({
	 * 						defaultText : 'Default status text',
	 * 						id : 'status-id',
	 * 						items : [{
	 * 									text : 'A Button'
	 * 								}, '-', 'Plain Text']
	 * 					})
	 * 		});
	 * 
	 * // By adding the statusAlign config, this will create the
	 * // exact same toolbar, except the status and toolbar item
	 * // layout will be reversed from the previous example:
	 * new Ext.Panel({
	 * 			title : 'StatusBar',
	 * 			// etc.
	 * 			bbar : new Ext.ux.StatusBar({
	 * 						defaultText : 'Default status text',
	 * 						id : 'status-id',
	 * 						statusAlign : 'right',
	 * 						items : [{
	 * 									text : 'A Button'
	 * 								}, '-', 'Plain Text']
	 * 					})
	 * 		});
	 * </code></pre>
	 */
	/**
	 * @cfg {String} defaultText The default {@link #text} value. This will be
	 *      used anytime the status bar is cleared with the
	 *      <tt>useDefaults:true</tt> option (defaults to '').
	 */
	/**
	 * @cfg {String} defaultIconCls The default {@link #iconCls} value (see the
	 *      iconCls docs for additional details about customizing the icon).
	 *      This will be used anytime the status bar is cleared with the
	 *      <tt>useDefaults:true</tt> option (defaults to '').
	 */
	/**
	 * @cfg {String} text A string that will be rendered into the status element
	 *      as the status message (defaults to '');
	 */
	/**
	 * @cfg {String} iconCls A CSS class that will be applied to the status
	 *      element and is expected to provide a background image that will
	 *      serve as the status bar icon (defaults to ''). The class is applied
	 *      directly to the div that also contains the status text, so the rule
	 *      should provide the appropriate padding on the div to make room for
	 *      the image. Example usage:
	 * 
	 * <pre><code>
	 * 	// Example CSS rule:
	 * 	.x-statusbar .x-status-custom {
	 * 	padding-left: 25px;
	 * 	background: transparent url(images/custom-icon.gif) no-repeat 3px 3px;
	 * 	}
	 * 
	 * 	// Initializing the status bar:
	 * 	var sb = new Ext.ux.StatusBar({
	 * 	defaultIconCls: 'x-status-custom'
	 * 	});
	 * 
	 * 	// Setting it in code:
	 * 	sb.setStatus({
	 * 	text: 'New status',
	 * 	iconCls: 'x-status-custom'
	 * 	});
	 * 	
	 * </code></pre>
	 */

	/**
	 * @cfg {String} cls The base class applied to the containing element for
	 *      this component on render (defaults to 'x-statusbar')
	 */
	cls : 'x-statusbar',
	/**
	 * @cfg {String} busyIconCls The default {@link #iconCls} applied when
	 *      calling {@link #showBusy} (defaults to 'x-status-busy'). It can be
	 *      overridden at any time by passing the <tt>iconCls</tt> argument
	 *      into <tt>showBusy</tt>. See the iconCls docs for additional
	 *      details about customizing the icon.
	 */
	busyIconCls : 'x-status-busy',
	/**
	 * @cfg {String} busyText The default {@link #text} applied when calling
	 *      {@link #showBusy} (defaults to 'Loading...'). It can be overridden
	 *      at any time by passing the <tt>text</tt> argument into
	 *      <tt>showBusy</tt>.
	 */
	busyText : 'Loading...',
	/**
	 * @cfg {Number} autoClear The number of milliseconds to wait after setting
	 *      the status via {@link #setStatus} before automatically clearing the
	 *      status text and icon (defaults to 5000). Note that this only applies
	 *      when passing the <tt>clear</tt> argument to setStatus since that
	 *      is the only way to defer clearing the status. This can be overridden
	 *      by specifying a different <tt>wait</tt> value in setStatus. Calls
	 *      to {@link #clearStatus} always clear the status bar immediately and
	 *      ignore this value.
	 */
	autoClear : 5000,

	// private
	activeThreadId : 0,

	// private
	initComponent : function() {
		if (this.statusAlign == 'right') {
			this.cls += ' x-status-right';
		}
		Ext.ux.StatusBar.superclass.initComponent.call(this);
	},

	// private
	afterRender : function() {
		Ext.ux.StatusBar.superclass.afterRender.call(this);

		var right = this.statusAlign == 'right';
		this.statusEl = new Ext.Toolbar.TextItem({
					cls : 'x-status-text '
							+ (this.iconCls || this.defaultIconCls || ''),
					text : this.text || this.defaultText || ''
				});

		if (right) {
			this.add('->');
			this.add(this.statusEl);
		} else {
			this.insert(0, this.statusEl);
			this.insert(1, '->');
		}

		// this.statusEl = td.createChild({
		// cls: 'x-status-text ' + (this.iconCls || this.defaultIconCls || ''),
		// html: this.text || this.defaultText || ''
		// });
		// this.statusEl.unselectable();

		// this.spacerEl = td.insertSibling({
		// tag: 'td',
		// style: 'width:100%',
		// cn: [{cls:'ytb-spacer'}]
		// }, right ? 'before' : 'after');
	},

	/**
	 * Sets the status {@link #text} and/or {@link #iconCls}. Also supports
	 * automatically clearing the status that was set after a specified
	 * interval.
	 * 
	 * @param {Object/String}
	 *            config A config object specifying what status to set, or a
	 *            string assumed to be the status text (and all other options
	 *            are defaulted as explained below). A config object containing
	 *            any or all of the following properties can be passed:
	 *            <ul>
	 *            <li><tt>text</tt> {String} : (optional) The status text to
	 *            display. If not specified, any current status text will remain
	 *            unchanged.</li>
	 *            <li><tt>iconCls</tt> {String} : (optional) The CSS class
	 *            used to customize the status icon (see {@link #iconCls} for
	 *            details). If not specified, any current iconCls will remain
	 *            unchanged.</li>
	 *            <li><tt>clear</tt> {Boolean/Number/Object} : (optional)
	 *            Allows you to set an internal callback that will automatically
	 *            clear the status text and iconCls after a specified amount of
	 *            time has passed. If clear is not specified, the new status
	 *            will not be auto-cleared and will stay until updated again or
	 *            cleared using {@link #clearStatus}. If <tt>true</tt> is
	 *            passed, the status will be cleared using {@link #autoClear},
	 *            {@link #defaultText} and {@link #defaultIconCls} via a fade
	 *            out animation. If a numeric value is passed, it will be used
	 *            as the callback interval (in milliseconds), overriding the
	 *            {@link #autoClear} value. All other options will be defaulted
	 *            as with the boolean option. To customize any other options,
	 *            you can pass an object in the format:
	 *            <ul>
	 *            <li><tt>wait</tt> {Number} : (optional) The number of
	 *            milliseconds to wait before clearing (defaults to
	 *            {@link #autoClear}).</li>
	 *            <li><tt>anim</tt> {Number} : (optional) False to clear the
	 *            status immediately once the callback executes (defaults to
	 *            true which fades the status out).</li>
	 *            <li><tt>useDefaults</tt> {Number} : (optional) False to
	 *            completely clear the status text and iconCls (defaults to true
	 *            which uses {@link #defaultText} and {@link #defaultIconCls}).</li>
	 *            </ul>
	 *            </li>
	 *            </ul>
	 *            Example usage:
	 * 
	 * <pre><code>
	 * // Simple call to update the text
	 * statusBar.setStatus('New status');
	 * 
	 * // Set the status and icon, auto-clearing with default options:
	 * statusBar.setStatus({
	 * 			text : 'New status',
	 * 			iconCls : 'x-status-custom',
	 * 			clear : true
	 * 		});
	 * 
	 * // Auto-clear with custom options:
	 * statusBar.setStatus({
	 * 			text : 'New status',
	 * 			iconCls : 'x-status-custom',
	 * 			clear : {
	 * 				wait : 8000,
	 * 				anim : false,
	 * 				useDefaults : false
	 * 			}
	 * 		});
	 * </code></pre>
	 * 
	 * @return {Ext.ux.StatusBar} this
	 */
	setStatus : function(o) {
		o = o || {};

		if (typeof o == 'string') {
			o = {
				text : o
			};
		}
		if (o.text !== undefined) {
			this.setText(o.text);
		}
		if (o.iconCls !== undefined) {
			this.setIcon(o.iconCls);
		}

		if (o.clear) {
			var c = o.clear, wait = this.autoClear, defaults = {
				useDefaults : true,
				anim : true
			};

			if (typeof c == 'object') {
				c = Ext.applyIf(c, defaults);
				if (c.wait) {
					wait = c.wait;
				}
			} else if (typeof c == 'number') {
				wait = c;
				c = defaults;
			} else if (typeof c == 'boolean') {
				c = defaults;
			}

			c.threadId = this.activeThreadId;
			this.clearStatus.defer(wait, this, [c]);
		}
		return this;
	},

	/**
	 * Clears the status {@link #text} and {@link #iconCls}. Also supports
	 * clearing via an optional fade out animation.
	 * 
	 * @param {Object}
	 *            config (optional) A config object containing any or all of the
	 *            following properties. If this object is not specified the
	 *            status will be cleared using the defaults below:
	 *            <ul>
	 *            <li><tt>anim</tt> {Boolean} : (optional) True to clear the
	 *            status by fading out the status element (defaults to false
	 *            which clears immediately).</li>
	 *            <li><tt>useDefaults</tt> {Boolean} : (optional) True to
	 *            reset the text and icon using {@link #defaultText} and
	 *            {@link #defaultIconCls} (defaults to false which sets the text
	 *            to '' and removes any existing icon class).</li>
	 *            </ul>
	 * @return {Ext.ux.StatusBar} this
	 */
	clearStatus : function(o) {
		o = o || {};

		if (o.threadId && o.threadId !== this.activeThreadId) {
			// this means the current call was made internally, but a newer
			// thread has set a message since this call was deferred. Since
			// we don't want to overwrite a newer message just ignore.
			return this;
		}

		var text = o.useDefaults ? this.defaultText : '', iconCls = o.useDefaults
				? (this.defaultIconCls ? this.defaultIconCls : '')
				: '';

		if (o.anim) {
			this.statusEl.fadeOut({
						remove : false,
						useDisplay : true,
						scope : this,
						callback : function() {
							this.setStatus({
										text : text,
										iconCls : iconCls
									});
							this.statusEl.show();
						}
					});
		} else {
			// hide/show the el to avoid jumpy text or icon
			this.statusEl.hide();
			this.setStatus({
						text : text,
						iconCls : iconCls
					});
			this.statusEl.show();
		}
		return this;
	},

	/**
	 * Convenience method for setting the status text directly. For more
	 * flexible options see {@link #setStatus}.
	 * 
	 * @param {String}
	 *            text (optional) The text to set (defaults to '')
	 * @return {Ext.ux.StatusBar} this
	 */
	setText : function(text) {
		this.activeThreadId++;
		this.text = text || '';
		if (this.rendered) {
			this.statusEl.setText(this.text);
		}
		return this;
	},

	/**
	 * Returns the current status text.
	 * 
	 * @return {String} The status text
	 */
	getText : function() {
		return this.text;
	},

	/**
	 * Convenience method for setting the status icon directly. For more
	 * flexible options see {@link #setStatus}. See {@link #iconCls} for
	 * complete details about customizing the icon.
	 * 
	 * @param {String}
	 *            iconCls (optional) The icon class to set (defaults to '', and
	 *            any current icon class is removed)
	 * @return {Ext.ux.StatusBar} this
	 */
	setIcon : function(cls) {
		this.activeThreadId++;
		cls = cls || '';

		if (this.rendered) {
			if (this.currIconCls) {
				this.statusEl.removeClass(this.currIconCls);
				this.currIconCls = null;
			}
			if (cls.length > 0) {
				this.statusEl.addClass(cls);
				this.currIconCls = cls;
			}
		} else {
			this.currIconCls = cls;
		}
		return this;
	},

	/**
	 * Convenience method for setting the status text and icon to special values
	 * that are pre-configured to indicate a "busy" state, usually for loading
	 * or processing activities.
	 * 
	 * @param {Object/String}
	 *            config (optional) A config object in the same format supported
	 *            by {@link #setStatus}, or a string to use as the status text
	 *            (in which case all other options for setStatus will be
	 *            defaulted). Use the <tt>text</tt> and/or <tt>iconCls</tt>
	 *            properties on the config to override the default
	 *            {@link #busyText} and {@link #busyIconCls} settings. If the
	 *            config argument is not specified, {@link #busyText} and
	 *            {@link #busyIconCls} will be used in conjunction with all of
	 *            the default options for {@link #setStatus}.
	 * @return {Ext.ux.StatusBar} this
	 */
	showBusy : function(o) {
		if (typeof o == 'string') {
			o = {
				text : o
			};
		}
		o = Ext.applyIf(o || {}, {
					text : this.busyText,
					iconCls : this.busyIconCls
				});
		return this.setStatus(o);
	}
});
Ext.reg('statusbar', Ext.ux.StatusBar);
